from __future__ import division
from django.shortcuts import render_to_response
from django.http import (HttpResponseRedirect, HttpResponse, 
   HttpResponseBadRequest, HttpResponseNotFound)
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.contrib.auth import forms as authforms
from django.template import Context, RequestContext
from django.db import models
from django.forms import ModelForm
from django.db.models import Q
from django.contrib.comments.models import Comment
from django.contrib.comments.signals import comment_will_be_posted
from pottononline.classifieds.models import Ad
from utils import slugify
from models import *
from PIL import Image, ImageFont, ImageDraw
import smtplib
import pottononline.gmailaccess
import random
import copy
import hashlib
import operator
import datetime




# A few trial hacks

# 1.  Keep the thumbs icons in memory all the time, they're tiny and will get hit quite a lot.
thumbdir = os.path.join(os.path.split(__file__)[0], "..", "media", "graphics")
thumbs_up   = Image.open(thumbdir+'/thupbw.png')
thumbs_down = Image.open(thumbdir+'/thdnbw.png')

# 2.  Same with the font
fontdir = os.path.join(os.path.split(__file__)[0], "..", "media", "fonts")
fontfile = fontdir+"/DejaVuSans.ttf"
font = ImageFont.truetype(fontfile, 9)


def wrongurl(request):
  html = """<html><head></head><body><h1>Sorry - you're using the wrong URL. </h1>You should be using <a href="http://www.pottononline.net">www.PottonOnline.net</a><br>
  </body></html>"""
  return HttpResponse(html)

def main(request):
  #Don't detect browser version you say?  Bollocks to you.  IE6 has caused more delays than anything else in this whole project.  Sick of it now.
  browser = request.META['HTTP_USER_AGENT']
  if "MSIE 6.0" in browser:
    bad_browser = True
  else:  bad_browser = False
  render_data = combine_dicts({'bad_browser':bad_browser})
  return render_to_response("map/main_page.html",render_data,context_instance=RequestContext(request))

def map(request, map_type):
  browser = request.META['HTTP_USER_AGENT']
  if "MSIE 6.0" in browser:
    bad_browser = True
  else:  bad_browser = False
  if map_type != None: 
    types = map_type.strip().split('/')
  else:
    types=[]
 
  typelookup = {}
  q_list = []
  markertypes=[]
  mtypes=[]
  
  # Bodge - fix this.
  for stype in MarkerType.objects.all():
    typelookup[stype.safename()] = stype.name
  
  if len(types) > 0:
      for each in types:
        try:
          type_object = MarkerType.objects.get(name=typelookup[each])
          markertypes.append(type_object)
          q_object = Q(itemtype=type_object)
          q_list.append(q_object)
        except KeyError:
          continue
      if len(q_list) > 0:
         queryset = Marker.objects.filter(active=True).filter(reduce(operator.or_, q_list))
         return render_to_response('map/map.html', {'markers':queryset, 'bad_browser':bad_browser, 'markertypes':markertypes,'icons': Icon.objects.exclude(shadow=None)},
          context_instance=RequestContext(request))         
      else:
        queryset = Marker.objects.filter(active=True)
        return render_to_response('map/map.html', {'all':'all', 'markers':queryset, 'bad_browser':bad_browser, 'markertypes':MarkerType.objects.all(), 'icons': Icon.objects.exclude(shadow=None)}, 
          context_instance=RequestContext(request)) 

  else:
    # No list of map marker types, so render them all
    queryset = Marker.objects.filter(active=True)
    return render_to_response('map/map.html', {'all':'all', 'markers':queryset, 'bad_browser':bad_browser, 'markertypes':MarkerType.objects.all(), 'icons': Icon.objects.exclude(shadow=None)}, 
      context_instance=RequestContext(request))  

@login_required
def edit(request):
  if request.user.is_authenticated():
    if request.user.is_superuser:
      markers = Marker.objects.all()
    else:
      markers = Marker.objects.filter(owner_user = request.user)
    markertypes = MarkerType.objects.all()
    newmarkericon = Icon.objects.get(image='green.png').id
    dict = {'markers': markers, 'markertypes': markertypes, 'icons' : Icon.objects.exclude(shadow=None), 'newmarkericon':newmarkericon }
    render_data = combine_dicts(dict)
    return render_to_response('map/edit.html', render_data,context_instance=RequestContext(request))

@login_required
def save(request):
  if request.user.is_authenticated():
    # create a quick lookup table to convert between a types safename and realname
    # NOTE TO SELF:  Return the PK ID rather than the safename - much easier!
    typelookup = {}
    for stype in MarkerType.objects.all():
      typelookup[stype.safename()] = stype.name
    for deleteid in request.POST.getlist("delete"):
      loc = Marker.objects.get(pk=int(deleteid))
      if loc.owner_user == request.user or request.user.is_superuser:
        loc.delete()
      else:
        continue
    for data in request.POST.getlist("change"):
      uid, lat, lon, name, descr, itype, price, creator = data.split('\x1c')
      if price=="None": price=None
      loc = Marker.objects.get(pk=int(uid))
      loc.lat, loc.lon, loc.name, loc.description = lat, lon, name, descr
      loc.price, loc.creator = price, creator
      loc.itemtype = MarkerType.objects.get(name=typelookup[itype])
      if loc.owner_user == request.user or request.user.is_superuser:
        loc.save()
      else:
        continue
    for data in request.POST.getlist("new"):
      loc = Marker()
      loc.lat, loc.lon, loc.name, loc.description, itype  = data.split('\x1c')
      loc.itemtype = MarkerType.objects.get(name=typelookup[itype])
      loc.owner_user = request.user
      loc.slug = slugify(loc, "name", "slug")
      loc.save()
    return HttpResponseRedirect("..")
  else:
    return HttpResponseRedirect('/login/')

def links(request):
    return HttpResponseRedirect('/')
    #markers = Marker.objects.all()
    #markertypes = MarkerType.objects.all()
    #return render_to_response('map/links.html',
    #{'markers':markers, 'markertypes':markertypes},
    #context_instance=RequestContext(request)
    #)

def detail(request, element_id):
  if element_id != None:
    marker = Marker.objects.get(pk=int(element_id))
    if marker.active == False:  return HttpResponseRedirect('/')
    if request.user.is_authenticated():
      user = request.user
      has_rated = Rater.objects.filter(rater=user, rateitem=marker).count()
      if has_rated > 1:  stars_writable = False  # CHANGE THIS!! ######################################################
      else: stars_writable = True
    else:
      stars_writable = False
    width = 18 * int(marker.rating_out_of_five())
    if marker.premium > 0:
      merchant_objects = MerchantObject.objects.filter(related_marker = marker)
      dict = {'marker':marker, 'stars_writable':stars_writable, 'width':width, 'merchant_objects':merchant_objects}
      render_data = combine_dicts(dict)
      return render_to_response('map/detail.html',render_data , context_instance=RequestContext(request))
    else:
      dict = {'marker':marker, 'stars_writable':stars_writable, 'width':width}
      render_data = combine_dicts(dict)
      return render_to_response('map/detail.html',render_data , context_instance=RequestContext(request))
  else:
    return HttpResponseRedirect("/")

def detail_all(request):
    markers = Marker.objects.filter(active=True) 
    return render_to_response('map/allmarkers.html', {'markers':markers} ,context_instance=RequestContext(request))
     
def detail_noid(request):
  return HttpResponseRedirect("/detail/all")

def section(request, section_name):
  type_list = section_name.strip().split('/')
  if type_list[0] == "all":
    if request.GET.has_key('page'):
      page = request.GET['page']
      startslice = int(page)*25
      endslice = startslice+25
      markers = Marker.objects.filter(active=True)[startslice:endslice]
      previouspage = False
      if markers.count() < 25:
        nextpage = False
      else:
        nextpage = int(page) + 1
    else:
      nextpage = 2
      previouspage = False
      markers = Marker.objects.filter(active=True)[0:25]
    if nextpage > 2: previouspage = nextpage -1 
    dict = {'markers':markers, 'title':'Where to go', 'mapurl':'', 'typelist':['All'], 'nextpage':nextpage, 'previouspage':previouspage}
    render_data = combine_dicts(dict)
    return render_to_response('map/section.html',render_data, context_instance=RequestContext(request))
  if len(type_list) > 0:
    # Nasty way of getting type object from safename (which is a method of type).  Need to improve this
    typelookup = {}
    for atype in MarkerType.objects.all():
      typelookup[atype.safename()] = atype.name
    q_list,t_list = [], []
    try:
      for each in type_list:
        type_object = MarkerType.objects.get(name=typelookup[each])
        q_object = Q(itemtype=type_object)
        q_list.append(q_object)
        t_list.append(str(type_object))
      queryset = Marker.objects.filter(active=True).filter(reduce(operator.or_, q_list))
      dict = {'markers':queryset, 'title':'Where to go', 'mapurl':section_name, 'typelist':t_list}
      render_data = combine_dicts(dict)
      return render_to_response('map/section.html', render_data, context_instance=RequestContext(request))
    except KeyError:
      dict = {'zero':'zero'}
      render_data = combine_dicts(dict)
      return render_to_response('map/section.html', render_data, context_instance=RequestContext(request))
  else:
    dict = {'zero':'zero'}
    render_data = combine_dicts(dict)  
    return render_to_response('map/section.html', render_data, context_instance=RequestContext(request))  

def send_email_via_gmail(msgfrom, msgto, msgsubj, msgtxt):
  msgsubj = "[PottonOnline]  "+msgsubj
  gmailuser = pottononline.gmailaccess.username
  gmailpassword = pottononline.gmailaccess.password
  header = u"From: %s\r\nTo: %s\r\nSubject: %s\r\nX-Mailer: pottononline.net\r\n\r\n" % (msgfrom, msgto, msgsubj)
  srv=smtplib.SMTP("smtp.gmail.com",587)
  srv.ehlo()
  srv.starttls()
  srv.ehlo()
  srv.login(gmailuser, gmailpassword)
  srv.sendmail(gmailuser, msgto, header+msgtxt)
  srv.close()

class AccountSignupForm(UserCreationForm):
  first_name = forms.CharField(label="First Name", required=True) 
  last_name = forms.CharField(label="Last name", required=True)
  email = forms.EmailField(label="Email address", required=False, help_text="If you already have an email address enter it here")
  address = forms.CharField(label="Address")
  phoneno = forms.RegexField(label="Phone number", max_length=12, regex=r'[0-9\_\-]')

def signup(request):
  if request.method == "GET":
    form = AccountSignupForm()
    dict = {"form":form}
    render_data = combine_dicts(dict)
    return render_to_response('map/signup.html', render_data, context_instance=RequestContext(request))
  if request.method == "POST":
    form = AccountSignupForm(request.POST)
    dict = {"form":form}
    render_data = combine_dicts(dict)
    if not form.is_valid():
      return render_to_response('map/signup.html', render_data, context_instance=RequestContext(request))
    
    # create a user account
    user = User.objects.create_user(
      form.cleaned_data["username"],
      form.cleaned_data["email"],
      form.cleaned_data["password1"],
    )
    user.is_active = False
    user.first_name=form.cleaned_data["first_name"]
    user.last_name=form.cleaned_data["last_name"]
    user.save()
    userdetails = '\n'.join([
      "%s: %s" % (field.name, getattr(user, field.name))
      for field in user._meta.fields])
    useradminurl = "http://localhost:8000/admin/auth/user/%s/" % user.id
    try:
      #ipaddr = request.META['REMOTE_ADDR']
      ipaddr = request.META['HTTP_X_FORWARDED_FOR']
    except:
      ipaddr = "Unknown"
      
    msgtxt = """A new user has requested access to pottononline. Here are their details:
      %s
      
      You can approve their account by going to %s and ticking "is active".
      
      IP Address: %s
      """ % (userdetails, useradminurl, ipaddr)
    send_email_via_gmail("accounts@pottononline.net", "admin@pottononline.net", "Sign Up Request", msgtxt)
    dict = {"user": user}
    render_data = combine_dicts(dict)
    return render_to_response('map/signedup.html', render_data, context_instance=RequestContext(request))
    

def do_logout(request):
  logout(request)
  return HttpResponseRedirect("/")

class AddPointForm(ModelForm):
  date_of_event = forms.DateField(widget=forms.DateTimeInput(format='%d/%m/%y'),input_formats=['%d/%m/%y','%d/%m/%Y'],required=False, help_text="dd/mm/yy", label="Start date")
  class Meta:
    model = PendingMarker
    exclude = ('date_of_event')

def addpoint(request):
  if request.method == "POST":
    form = AddPointForm(request.POST)
    if form.is_valid():
      pendingmarker = form.save(commit=False)
      if request.user.is_authenticated():
        pendingmarker.owner_user = request.user
      else:
        pendingmarker.owner_user = None  
      pendingmarker.save()    
      # Send notification email...
      msgtxt = u"""
      A new marker has been added to the map and needs approval.
      
      Please log in and check the new addition.  The details are:
       
      Name:  %s
      Descr:  %s
      Type: %s
      Map link: %s
      """ % (pendingmarker.marker_name, pendingmarker.marker_descr, pendingmarker.marker_type.safename(), pendingmarker.staticmap_me())
      if pendingmarker.owner_user != None:
        msgtxt += """User:  %s""" % pendingmarker.owner_user.username
      send_email_via_gmail(u"accounts@pottononline.net", u"admin@pottononline.net", "Marker requires approval.",msgtxt)
      return HttpResponseRedirect("/thanks?marker")
    else:
      dict = {'form':form}
      render_data = combine_dicts(dict)
      return render_to_response('map/addpoint.html', render_data , context_instance=RequestContext(request))
  else:
    if not request.user.is_authenticated():
      form = AddPointForm()
      dict = {'form':form}
      render_data = combine_dicts(dict)
      return render_to_response('map/addpoint.html',render_data , context_instance=RequestContext(request))
    else:
      a = str(request.user.first_name).capitalize()+' '+str(request.user.last_name).capitalize()
      editors_name = request.user.username
      form = AddPointForm(initial={'editors_name':editors_name, 'editors_email':request.user.email})
      dict = {'form':form}
      render_data = combine_dicts(dict)
      return render_to_response('map/addpoint.html',render_data , context_instance=RequestContext(request))
 
@login_required
def review_pending(request):
  if request.method == "GET":
    if request.user.is_superuser:
      pendingmarkers = PendingMarker.objects.all()
      return render_to_response("map/reviewpending.html", {"pendingmarkers" : pendingmarkers}, context_instance=RequestContext(request))
    else:
      return HttpResponseRedirect("/")
  if request.method == "POST":
    formdata = [ f for f in request.POST.items() ]
    data = u''
    for each in formdata:
        try:
          id = each[0].split('radio')[1]
          action = each[1]
          data += id+" "+action
          if action == "Remove":
            data += "Deleteing " +id
            pm = PendingMarker.objects.get(pk=int(id))
            pm.delete()
          if action == "Approve":
            pm = PendingMarker.objects.get(pk=int(id))
            nm = Marker()
            if pm.owner_user == None:
              nm.name          = pm.marker_name
            else:
              nm.name = pm.marker_name
            nm.creator       = pm.editors_name
            nm.private_email = pm.editors_email
            nm.itemtype      = pm.marker_type
            nm.lat           = pm.marker_lat
            nm.lon           = pm.marker_lng
            nm.description   = pm.marker_descr
            nm.rateable      = True
            nm.commentable   = True
            if pm.date_of_event != '':
              try:
                nm.date_due      = pm.date_of_event
              except:
                pass
            if pm.owner_user:
              nm.owner_user = pm.owner_user
            nm.slug = slugify(nm, "name", "slug")
            nm.save()
            pm.delete()
        except:
          pass
    return HttpResponse(data)
    
    
# Comment Voting
#

@login_required
def vote_on_comment(request):
  if request.user.is_authenticated() and request.method == "POST" and request.is_ajax():
    user = request.user
    try:
      comment_id = request.POST.__getitem__('commentid')
    except:
      return HttpResponse("No Comment ID")
    try:
      vote_dir = request.POST.__getitem__('votedirection')
    except:
      vote_dir = "down"
    try:
      return_type = request.POST.__getitem__('returntype')
    except:
      return_type = "goodbad"
    comment = Comment.objects.get(pk=int(comment_id))
    has_voted = Voter.objects.filter(voter=user, voteitem=comment)
    if has_voted.count() >= 1: # REMEMBER TO CHANGE THIS!!! ######################################################################
      return HttpResponseBadRequest()
    else:
      register_vote = Voter()
      register_vote.voter = request.user
      register_vote.voteitem = comment
      register_vote.save()
      # Are there already some votes on this comment?
      num = RatingOnComment.objects.filter(voted_comment=comment).count()
      if num == 1:
        vote = RatingOnComment.objects.get(voted_comment=comment)
      elif num > 1:
        vote = RatingOnComment.objects.filter(voted_comment=comment)[0]
      else:
        vote = RatingOnComment()
        vote.voted_comment = comment
      if vote_dir == "up":
        results = vote.vote_up()
      else:
        results = vote.vote_down()
      vote.save()
      if return_type == "percentage":
        return HttpResponse(vote.percentage_good())
      else:
        return HttpResponse(vote.good_vs_bad())
  else:
    try:
      comment_id = request.GET.__getitem__('commentid')
      return_type = request.GET.__getitem__('returntype')
    except:  return HttpResponse("FAIL")
    comment = Comment.objects.get(pk=int(comment_id))
    voting = RatingOnComment.objects.get(voted_comment=comment)
    if return_type == "percentage":
      return HttpResponse(voting.percentage_good())
    elif return_type == "goodbad":
      return HttpResponse(voting.good_vs_bad())
    else:
      return HttpResponse(voting.votes_total)
      
def return_rating_image(request):
  if request.method == "GET":
    try:
      return_type = request.GET.__getitem__('returntype')
    except:
      return_type = "percentage"
    comment_id = request.GET.__getitem__('comment_id')
    comment = Comment.objects.get(pk=int(comment_id))
    try:
      results = RatingOnComment.objects.get(voted_comment=comment)
    except:
      results = None
    if return_type == "percentage":
      im = Image.new("RGB", (25,16), (255,255,255,255))
      dr = ImageDraw.Draw(im)
      if results != None:
        if int(results.percentage_good()) > 50: fill='#000000'
        else: fill='#ff0000'
        dr.text((1,1),str(results.percentage_good())+'%', font=font, fill=fill)
      else:
        fill = "#0000ff"
        dr.text((2,1),"0"+'%', font=font, fill=fill)
      response = HttpResponse(mimetype="image/png")
      im.save(response, "PNG")
      return response
    elif return_type == "good":
      if results != None:
        textstr = str(results.votes_plus)
        if textstr == "None": textstr = "0"
      else:
        textstr = "0"
      im = ''
      im = copy.copy(thumbs_up)
      dr = ImageDraw.Draw(im)
      dr.text((0,13),textstr, font=font, fill='#000000')
      response = HttpResponse(mimetype="image/png")
      im.save(response, "PNG")
      return response
    else:
      if results != None:
        textstr = str(results.votes_minus)
      else:
        textstr = "0"
      im = ''
      im = copy.copy(thumbs_down)
      dr = ImageDraw.Draw(im)
      if textstr == "None": textstr ="0"
      dr.text((0,13),textstr, font=font, fill='#000000')
      response = HttpResponse(mimetype="image/png")
      im.save(response, "PNG")
      return response  
  else:
    return HttpResponseBadRequest()


def stars_rating(request):
  if request.user.is_authenticated() and request.method == "POST" and request.is_ajax():
    user = request.user
    rating = int(request.POST.__getitem__('rating')[0])
    mid = int(str(request.POST.__getitem__('id')).split('srater')[1])
    marker = Marker.objects.get(pk = mid)
    current_total_rating = marker.rating
    if current_total_rating == None:  current_total_rating = 0
    current_number_votes = marker.total_rates
    if current_number_votes == None:  current_number_votes = 0
    current_total_rating += rating
    current_number_votes += 1
    marker.rating = current_total_rating
    marker.total_rates = current_number_votes
    marker.save()
    arater = Rater()
    arater.rater = user
    arater.rateitem = marker
    arater.save()
    return HttpResponse(marker.rating_out_of_five())
  else:  return HttpResponseBadRequest()
    
class DetailEditForm(forms.Form):
  active      = forms.BooleanField(required=False)
  name        = forms.CharField(max_length=50, required=False)
  mtype       = forms.ModelChoiceField(label="Type",queryset=MarkerType.objects.all(), required=False)
  publicemail = forms.EmailField(max_length=50, required=False, label="Email")
  publicphone = forms.CharField(max_length=50, required=False, label="Phone")
  link        = forms.URLField(max_length=500, verify_exists=True, required=False, label="Website link")
  date_due    = forms.DateField(widget=forms.DateTimeInput(format='%d/%m/%y'),input_formats=['%d/%m/%y','%d/%m/%Y'],required=False, help_text="dd/mm/yy", label="Start date")
  date_ends   = forms.DateField(widget=forms.DateTimeInput(format='%d/%m/%y'),input_formats=['%d/%m/%y','%d/%m/%Y'],required=False, help_text="dd/mm/yy", label="End date")
  descr       = forms.CharField(max_length=1000, required=False)
  freetext    = forms.CharField(max_length=5000, required=False)
  lat         = forms.CharField(required=False)
  lng         = forms.CharField(required=False)
  price       = forms.CharField(max_length=50, required=False)
  address     = forms.CharField(max_length=50, required=False)
  image1      = forms.ImageField(required=False,error_messages={'invalid':'Invalid', 'invalid_image':'Not an image file'})
  image2      = forms.ImageField(required=False,error_messages={'invalid':'Invalid', 'invalid_image':'Not an image file'})
  image3      = forms.ImageField(required=False,error_messages={'invalid':'Invalid', 'invalid_image':'Not an image file'})

def fill_detail_form(data_in):
  if data_in == '': return None
  else: return data_in

@login_required
def detail_edit(request, element_id):
  if request.user.is_authenticated():
    if request.method == "POST":
      form = DetailEditForm(request.POST, request.FILES)
      marker = Marker.objects.get(pk=element_id)
      if request.user == marker.owner_user or request.user.is_superuser:
        if form.is_valid():
          formdict = form.cleaned_data
          if formdict['active']:
            marker.active=True
          else:
            marker.active=False
          marker.name         = fill_detail_form(formdict['name'])
          marker.itemtype     = formdict['mtype']
          marker.public_email = formdict['publicemail']
          marker.public_phone = formdict['publicphone']
          marker.date_due     = fill_detail_form(formdict['date_due'])
          marker.date_ends    = fill_detail_form(formdict['date_ends'])
          marker.description  = fill_detail_form(formdict['descr'])
          marker.freetext     = fill_detail_form(formdict['freetext'])
          marker.lat          = fill_detail_form(formdict['lat'])
          marker.lon          = fill_detail_form(formdict['lng'])
          marker.price        = fill_detail_form(formdict['price'])
          marker.address      = fill_detail_form(formdict['address'])
          if fill_detail_form(formdict['link']) != None:  marker.link = fill_detail_form(formdict['link'])
          else: marker.link = ''
          for each in  request.FILES.keys():
            image_num = str(each)
            image_num_t = image_num+'_t'
            main_image, image_thumb = handle_editimage_file(request.FILES[each],request.user, element_id, str(each))
            setattr(marker,image_num, main_image)
            setattr(marker,image_num_t, image_thumb)
            if marker.thumbnail == '' or marker.thumbnail == None:
              marker.thumbnail = image_thumb
          marker.save()
          return HttpResponseRedirect("/detail/"+str(marker.id))
        else:
          dict = {'form':form, 'marker':marker}
          render_data = combine_dicts(dict)
          render_to_response('map/detailedit.html',render_data , context_instance=RequestContext(request))
      else:
        return HttpResponseBadRequest()
    else:
      marker = Marker.objects.get(pk=element_id)
      ifd = {}
      ifd['active']      = marker.active
      ifd['name']        = marker.name
      ifd['mtype']       = marker.itemtype.id
      ifd['publicphone'] = marker.public_phone
      ifd['publicemail'] = marker.public_email
      ifd['date_due']    = marker.date_due
      ifd['date_ends']   = marker.date_ends
      ifd['descr']       = marker.description
      ifd['freetext']    = marker.freetext
      ifd['lat']         = marker.lat
      ifd['lng']         = marker.lon
      ifd['price']       = marker.price
      ifd['address']     = marker.address
      ifd['link']        = marker.link
      # bodge in the thumnails?      
      form = DetailEditForm(initial=ifd)
      merchant_objects,addmore = False, False
      merchant_objects = MerchantObject.objects.filter(related_marker=marker)
      if marker.premium > 0 and len(merchant_objects) < marker.premium:
        addmore = True
      dict = {'form':form, 'marker':marker, 'merchant_objects':merchant_objects, 'addmore':addmore}
      render_data = combine_dicts(dict)
    return render_to_response('map/detailedit.html', render_data , context_instance=RequestContext(request))
  else:
    return HttpResponse("You need to login to edit")
  
def handle_editimage_file(file,user,element_id,file_num):
  file_ext = file.name.split('.')[-1]
  if str(user) != 'AnonymousUser': # Fix this!
    if file._get_size() > 3145728: # 3MB enough?
      return None
    if file.content_type.split('/')[0] != "image":
      return None
    # Ok to go
    media_area = os.path.join(os.path.split(__file__)[0], "..", "media", "pictures")
    pic_hash = hashlib.sha224(str(element_id)+'-'+file_num).hexdigest()
    filename = pic_hash+'.'+file_ext
    asset_path = "/assets/pictures/"+filename
    asset_path_t = "/assets/pictures/t_"+filename
    save_path = media_area+'/'+filename
    
    destination = open(save_path, 'wb+')
    for chunk in file.chunks():
      destination.write(chunk)
    destination.close()
    # File saved to disk, now we can reopen and fiddle
    full_image = Image.open(save_path,"r")
    full_image.thumbnail((200,200), Image.ANTIALIAS)    
    #full_image.close()
    thumb_filename = media_area+'/'+'t_'+filename
    full_image.save(thumb_filename)
    return (asset_path, asset_path_t)
 
def search(request):
  if request.method != "POST":
    a = combine_dicts({})
    return render_to_response('map/search.html', a, context_instance=RequestContext(request))
  else:
    search_term = request.POST.__getitem__('search_term')
    markers = Marker.objects.filter(name__icontains=search_term)
    if len(markers) == 1:
      # Only one hit?  Direct to that page.  Woosome search.
      return HttpResponseRedirect('/%s' % markers[0].slug)
    else:
      dict = {'markers':markers}
      render_data = combine_dicts(dict)
      return render_to_response('map/search.html', render_data, context_instance=RequestContext(request))

class MerchantEditForm(ModelForm):
  image1      = forms.ImageField(required=False,error_messages={'invalid':'Invalid', 'invalid_image':'Not an image file'})
  date_due    = forms.DateField(widget=forms.DateTimeInput(format='%d/%m/%y'),input_formats=['%d/%m/%y','%d/%m/%Y'],required=False, help_text="dd/mm/yy", label="Start date")
  date_ends   = forms.DateField(widget=forms.DateTimeInput(format='%d/%m/%y'),input_formats=['%d/%m/%y','%d/%m/%Y'],required=False, help_text="dd/mm/yy", label="End date")
  class Meta:
    model = MerchantObject
    exclude = ('related_marker','image1', 'date_due', 'date_ends')
 
def handle_merchimage_file(file,user,element_id,file_num):
  file_ext = file.name.split('.')[-1]
  if str(user) != 'AnonymousUser': # Fix this!
    if file._get_size() > 3145728: # 3MB enough?
      return None
    if file.content_type.split('/')[0] != "image":
      return None
    # Ok to go
    media_area = os.path.join(os.path.split(__file__)[0], "..", "media", "pictures", "merchants")
    pic_hash = hashlib.sha224(str(random.random())).hexdigest()
    filename = str(element_id)+pic_hash+'.'+file_ext
    asset_path = "/assets/pictures/merchants/"+filename
    asset_path_t = "/assets/pictures/merchants/t_"+filename
    save_path = media_area+'/'+filename
    
    destination = open(save_path, 'wb+')
    for chunk in file.chunks():
      destination.write(chunk)
    destination.close()
    # File saved to disk, now we can reopen and fiddle
    full_image = Image.open(save_path,"r")
    full_image.thumbnail((200,200), Image.ANTIALIAS)    
    #full_image.close()
    thumb_filename = media_area+'/'+'t_'+filename
    full_image.save(thumb_filename)
    return (asset_path, asset_path_t)


@login_required
def merchantedit(request, **kwargs): #def merchantedit(request, marker_id, merch_obj_id):
  #  I know this is a right mess - I'll tidy it up one day.
  if request.method == "POST":
    # POST request
    if request.POST.has_key("Delete") and request.POST.has_key("reallydelete"):  # Delete request
        related_marker = Marker.objects.get(pk=kwargs['marker_id'])
        merchobj = MerchantObject.objects.get(pk=kwargs['merch_obj_id'])
        try:
          del_file = merchobj.image1.split('/')[-1]
          os.remove(media_area+'/'+del_file)
        except:
          pass
        try:
         del_tfile = merchobj.thumbnail.split('/')[-1]
         os.remove(media_area+'/'+del_tfile)
        except:
          pass
        merchobj.delete()
        return HttpResponseRedirect('/detail/'+str(related_marker.id)+'/edit')
    elif 'marker_id' in kwargs and 'merch_obj_id' in kwargs:
      marker_id, merch_obj_id = kwargs['marker_id'],kwargs['merch_obj_id']
      related_marker = Marker.objects.get(pk=marker_id)
      merchobj = MerchantObject.objects.get(pk=merch_obj_id)
      if request.user == related_marker.owner_user or user.is_superuser:
        f = MerchantEditForm(request.POST, request.FILES)
        if f.is_valid():
          edited_object = f.save(commit=False)
          edited_object.related_marker = related_marker
          edited_object.id = merchobj.id        
          for each in  request.FILES.keys():
            image_num = str(each)
            image_num_t = image_num+'_t'
            media_area = os.path.join(os.path.split(__file__)[0], "..", "media", "pictures", "merchants")
            try:
              del_file = merchobj.image1.split('/')[-1]
              os.remove(media_area+'/'+del_file)
            except:
              pass
            try:
              del_tfile = merchobj.thumbnail.split('/')[-1]
              os.remove(media_area+'/'+del_tfile)
            except:
              pass
            # And then upload the new ones
            main_image, image_thumb = handle_merchimage_file(request.FILES[each],request.user, marker_id, str(each))
            edited_object.image1 = main_image
            edited_object.thumbnail = image_thumb
          # All tests passed I think
          if len(request.FILES) == 0 and merchobj.image1 != '':
            edited_object.image1 = merchobj.image1
            edited_object.thumbnail = merchobj.thumbnail
          if MerchantObject.objects.filter(related_marker=related_marker).count() <= related_marker.premium:
            edited_object.save()
          return HttpResponseRedirect('/detail/'+str(related_marker.id)+'/edit')
        else:
          # Invalid form data
          dict = {'form':f, 'marker':related_marker, 'merchobj':merchobj}
          render_data = combine_dicts(dict)
          return render_to_response('map/edit_merchant_object.html',render_data , context_instance=RequestContext(request))
      else:
        #Not the correct user
        return HttpResponseRedirect('/')
    elif 'marker_id' in kwargs and 'merch_obj_id' not in kwargs:
      # Add a new marker
      marker_id = kwargs['marker_id']
      marker = Marker.objects.get(pk=marker_id)
      if request.user != marker.owner_user or not request.user.is_superuser:  return HttpResponseRedirect('/')
      f = MerchantEditForm(request.POST)
      if f.is_valid():
        edited_object = f.save(commit=False)
        edited_object.related_marker = marker
        for each in  request.FILES.keys():
          image_num = str(each)
          image_num_t = image_num+'_t'
          main_image, image_thumb = handle_merchimage_file(request.FILES[each],request.user, marker_id, str(each))
          edited_object.image1    = main_image
          edited_object.thumbnail = image_thumb
        if marker.premium > 0:
          edited_object.save()
        return HttpResponseRedirect('/detail/'+str(marker.id)+'/edit')
      else:
        dict =  {'form':f, 'marker':marker}
        render_data = combine_dicts(dict)
        return render_to_response('map/edit_merchant_object.html',render_data , context_instance=RequestContext(request))
    else:  return HttpResponseRedirect("/")  
  else:
    #GET request
    if   'marker_id' in kwargs and 'merch_obj_id' in kwargs:
      merch_obj = MerchantObject.objects.get(pk=kwargs['merch_obj_id'])
      marker = Marker.objects.get(pk=kwargs['marker_id'])
      form = MerchantEditForm(instance=merch_obj)
      if MerchantObject.objects.filter(related_marker=marker).count() <= marker.premium:
        dict = {'form':form, 'marker':marker, 'merchobj':merch_obj}
        render_data = combine_dicts(dict)
        return render_to_response('map/edit_merchant_object.html',render_data , context_instance=RequestContext(request))
      else:
        return HttpResponseRedirect('/detail/'+str(marker.id)+'/edit')
    elif 'marker_id' in kwargs and 'merch_obj_id' not in kwargs:
      marker = Marker.objects.get(pk=kwargs['marker_id'])
      form = MerchantEditForm()
      if MerchantObject.objects.filter(related_marker=marker).count() <= marker.premium:
        dict = {'form':form, 'marker':marker}
        render_data = combine_dicts(dict)
        return render_to_response('map/edit_merchant_object.html',render_data , context_instance=RequestContext(request))
      else:
        return HttpResponseRedirect('/detail/'+str(marker.id)+'/edit')
    else:
      return HttpResponseRedirect("/")
      

def detailmerch(request,element_id,merch_obj_id):
  marker = Marker.objects.get(pk=element_id)
  merch_obj = MerchantObject.objects.get(pk=merch_obj_id)
  if merch_obj.related_marker != marker:
    return HttpResponseRedirect("/")
  else:
    # Those two match
    if request.user.is_authenticated():
      user = request.user
      has_rated = MerchantRater.objects.filter(rater=user, rateitem=merch_obj).count()
      if has_rated >= 1:  stars_writable = False  # CHANGE THIS!! ######################################################
      else: stars_writable = True
    else:
      stars_writable = False
    width = 18 * int(marker.rating_out_of_five())
    dict = {'marker':merch_obj, 'width':merch_obj.rating_width(), 'stars_writable':stars_writable}
    render_data = combine_dicts(dict)
    return render_to_response('map/merchantdetail.html', render_data, context_instance=RequestContext(request))
    
def stars_rating_merchant(request):
  if request.user.is_authenticated() and request.method == "POST" and request.is_ajax():
    user = request.user
    rating = int(request.POST.__getitem__('rating')[0])
    mid = int(str(request.POST.__getitem__('id')).split('mrater')[1])
    marker = MerchantObject.objects.get(pk = mid)
    current_total_rating = marker.rating
    if current_total_rating == None:  current_total_rating = 0
    current_number_votes = marker.total_rates
    if current_number_votes == None:  current_number_votes = 0
    current_total_rating += rating
    current_number_votes += 1
    marker.rating = current_total_rating
    marker.total_rates = current_number_votes
    marker.save()
    arater = MerchantRater()
    arater.rater = user
    arater.rateitem = marker
    arater.save()
    return HttpResponse(marker.rating_out_of_five())
  else:  return HttpResponseBadRequest()      

def mymarkers(request):
    markers = Marker.objects.filter(owner_user=request.user) 
    dict = {'markers':markers}
    render_data = combine_dicts(dict)
    return render_to_response('map/allmarkers.html', render_data ,context_instance=RequestContext(request))
    
def standard_content(request,reference):
  text = "map/text/"+str(reference)
  dict = {'text':text}
  render_data = combine_dicts(dict)
  return render_to_response('map/standard.html',render_data,context_instance=RequestContext(request))
  
def event(request, event_id):
  event = PlainEvent.objects.get(pk=event_id)
  return render_to_response('map/event.html', {'event':event}, context_instance=RequestContext(request))

def static_map():
  # Return a URL to a static snapshot of the main map with up to 50 markers
  #http://code.google.com/apis/maps/documentation/staticmaps/
  colour_list = [ "brown", "green", "purple", "yellow", "blue", "gray", "orange", "red", "white" ]
  static_api = "ABQIAAAAhcP5rdJ8gtI2Tvrvo88B3BRheRdRZgitUVyZZmgoSSAEYuewghSEp04JWHUrJoHbRpqILk8pmfDG2g"
  static_map_url =  "http://maps.google.com/staticmap?key="+static_api+"&format=jpg&sensor=false&center=52.127699,-0.214148&maptype=hybrid&markers="
  markers = Marker.objects.order_by('?')[:50]
  last_type = ''
  first = True
  for marker in markers:
    if first:
      static_map_url += str(marker.lat)+','+str(marker.lon)+','
      first = False
    else: static_map_url += '|'+str(marker.lat)+','+str(marker.lon)+','
    if last_type != marker.itemtype:
      col = choice(colour_list)
    last_type = marker.itemtype  
    static_map_url += 'mid'+col
  static_map_url += "&size=640x640"+"&zoom=15"
  return static_map_url

@login_required  
def make_walks(request):
  if request.method=="GET":
    return render_to_response('map/polylines.html', righthand_boilerplate(),context_instance=RequestContext(request))
  elif request.method == "POST" and request.user.is_authenticated():
    route = Route()
    route.polyline = request.POST['results']
    route.name = request.POST['name']
    route.text = request.POST['descr']
    if request.user.is_authenticated():  route.owner_user = request.user
    route.active=False
    send_email_via_gmail("accounts@pottononline.net", "admin@pottononline.net", "New Route added", "Go to the admin interface and make it active")
    route.save()
    return HttpResponseRedirect("/thanks?marker")
  else:
    return HttpResponseBadRequest()

def show_walks(request, walk_id):
  if request.method == "GET":
    if not walk_id:
      walks = Route.objects.filter(active=True)
      dict = {'walks':walks, 'single':False}
      render_data = combine_dicts(dict)
      return render_to_response('map/showroutes.html', render_data, context_instance=RequestContext(request))
    else:
      walk = Route.objects.filter(pk=walk_id)
      single_walk = Route.objects.get(pk=walk_id)
      pois = Route_POI.objects.filter(related_route=walk_id).filter(active=True)
      if request.user.is_authenticated():
        user = request.user
        has_rated = RouteRater.objects.filter(rater=user, rateitem=single_walk).count()
        if has_rated > 1:  stars_writable = False  # CHANGE THIS!! ######################################################
        else: stars_writable = True
      else:
        stars_writable = False
      width = 18 * int(single_walk.rating_out_of_five())
      dict = {'walks':walk, 'single':'single', 'singlewalk':single_walk, 'pois':pois, 'width':width,'stars_writable':stars_writable}
      render_data = combine_dicts(dict)
      return render_to_response('map/showroutes.html', render_data, context_instance=RequestContext(request))
  else:  return HttpResponseBadRequest()
      
def handle_poi(request):
  if request.method == "POST" and request.is_ajax():
    if "Type your POI information here" in request.POST['text']:  return HttpResponseBadRequest()
    if "Enter POI name" in request.POST['name']: return HttpResponseBadRequest()
    poi = Route_POI()
    if request.user.is_authenticated():
      poi.owner_user = request.user
    poi.name = request.POST['name']
    poi.active = True
    poi.lat = request.POST['lat']
    poi.lon = request.POST['lon']
    poi.text = request.POST['text']
    poi.related_route = Route.objects.get(pk=request.POST['routeid'])
    poi.save()
    return HttpResponse('OK')
  else:
    return HttpResponseBadRequest  

def stars_rating_walks(request):
  if request.user.is_authenticated() and request.method == "POST" and request.is_ajax():
    user = request.user
    rating = int(request.POST.__getitem__('rating')[0])
    mid = int(str(request.POST.__getitem__('id')).split('wrater')[1])
    marker = Route.objects.get(pk = mid)
    current_total_rating = marker.rating
    if current_total_rating == None:  current_total_rating = 0
    current_number_votes = marker.total_rates
    if current_number_votes == None:  current_number_votes = 0
    current_total_rating += rating
    current_number_votes += 1
    marker.rating = current_total_rating
    marker.total_rates = current_number_votes
    marker.save()
    arater = RouteRater()
    arater.rater = user
    arater.rateitem = marker
    arater.save()
    return HttpResponse(marker.rating_out_of_five())
  else:  return HttpResponseBadRequest()
  
def righthand_boilerplate():
  today = datetime.date.today()
  yesterday = today-datetime.timedelta(1)
  twodaysago = today-datetime.timedelta(2)
  twoweeksago = today-datetime.timedelta(14)
  future = today+datetime.timedelta(4)
  long_event = Q(date_due__gt=twoweeksago) & Q(date_ends__gt=yesterday)
  coming_events = Marker.objects.filter(Q(date_due__gt=yesterday) | long_event)
  #(date_due__gt=twoweeksago).filter(date_ends__gt=yesterday).order_by('date_due')[:5]
  latest_comments = Comment.objects.order_by('-submit_date')[:10]
  latest_markers = Marker.objects.order_by('-lastupdate')[:10]
  featured_marker = Marker.objects.all().order_by('?')[1] # premium > 0 !
  notices = Notice.objects.order_by('-lastupdate')[:5]
  walks = Route.objects.order_by('-lastupdate')[:5]
  classifieds = Ad.objects.order_by('-created')[:5]
  return ({'big_map':static_map(),'events':coming_events, 'latestmarkers':latest_markers, 'comments':latest_comments,
   'featured':featured_marker, 'notices':notices, 'rh_walks':walks, 'ads':classifieds})
   
def combine_dicts(a):
  b = dict(a)
  b.update(righthand_boilerplate())
  return b

def thanks(request):
  if request.GET.has_key('marker'):
    text = "<h2>We will review your entry soon.<h2><br /><br />"
  return render_to_response('map/thanks.html', {'redir':'/', 'text':text})
  
def comments_callback(sender, **kwargs):
  today = datetime.date.today()
  request = kwargs['request']
  if request.user.is_authenticated():
    return True
  else:
    remote_ip = request.META['REMOTE_ADDR']
    comments = Comment.objects.filter(ip_address=remote_ip).filter(submit_date__day = today.day, submit_date__month = today.month,
      submit_date__year = today.year).count()
    if comments >= 3:
      return False
    else:  return True
  
comment_will_be_posted.connect(comments_callback)

def check_for_slug(request, slug):
    # See if this slug is actually a slug for a Marker
    try:
        m = Marker.objects.get(slug=slug)
        return detail(request, m.id)
    except Marker.DoesNotExist:
        return HttpResponseNotFound("not found")

